package org.example.review.service.impl;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.example.review.dto.ChangePasswordRequest;
import org.example.review.dto.LoginRequest;
import org.example.review.dto.LoginResponse;
import org.example.review.dto.UserDTO;
import org.example.review.mapper.UserMapper;
import org.example.review.service.UserService;
import org.springframework.stereotype.Service;

import java.util.UUID;

/**
 * 用户服务实现类
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class UserServiceImpl implements UserService {
    
    private final UserMapper userMapper;
    
    /**
     * 用户登录
     * @param loginRequest 登录请求信息
     * @return 登录响应，包含token和用户信息
     */
    @Override
    public LoginResponse login(LoginRequest loginRequest) {
        try {
            log.info("用户登录请求，用户名: {}", loginRequest.getUsername());
            
            // 参数验证
            if (loginRequest.getUsername() == null || loginRequest.getUsername().trim().isEmpty()) {
                log.warn("登录失败：用户名为空");
                throw new IllegalArgumentException("用户名不能为空");
            }
            if (loginRequest.getPassword() == null || loginRequest.getPassword().trim().isEmpty()) {
                log.warn("登录失败：密码为空");
                throw new IllegalArgumentException("密码不能为空");
            }
            
            // 查询用户
            UserDTO user = userMapper.selectByUsername(loginRequest.getUsername());
            if (user == null) {
                log.warn("登录失败：用户不存在，用户名: {}", loginRequest.getUsername());
                throw new IllegalArgumentException("用户名或密码错误");
            }
            
            // 验证密码
            if (!loginRequest.getPassword().equals(user.getPassword())) {
                log.warn("登录失败：密码错误，用户名: {}", loginRequest.getUsername());
                throw new IllegalArgumentException("用户名或密码错误");
            }
            
            // 检查用户状态
            if (user.getStatus() != null && ("离职".equals(user.getStatus()) || "禁用".equals(user.getStatus()))) {
                log.warn("登录失败：用户状态异常，用户名: {}, 状态: {}", loginRequest.getUsername(), user.getStatus());
                throw new IllegalArgumentException("该账户已被禁用或离职，请联系管理员");
            }
            
            // 生成token（简单实现，实际项目应使用JWT）
            String token = generateToken(user);
            
            // 清除密码字段（不返回给前端）
            user.setPassword(null);
            
            log.info("用户登录成功，用户名: {}, 用户ID: {}, 权限等级: {}", 
                    user.getUsername(), user.getUserId(), user.getAuthType());
            
            return LoginResponse.builder()
                    .token(token)
                    .user(user)
                    .build();
                    
        } catch (IllegalArgumentException e) {
            throw e;
        } catch (Exception e) {
            log.error("登录过程发生异常", e);
            throw new RuntimeException("登录失败，请稍后再试", e);
        }
    }
    
    /**
     * 根据用户ID获取用户信息
     * @param userId 用户ID
     * @return 用户信息
     */
    @Override
    public UserDTO getUserById(Integer userId) {
        try {
            log.info("查询用户信息，用户ID: {}", userId);
            if (userId == null) {
                throw new IllegalArgumentException("用户ID不能为空");
            }
            UserDTO user = userMapper.selectByUserId(userId);
            if (user == null) {
                log.warn("用户不存在，用户ID: {}", userId);
                throw new IllegalArgumentException("用户不存在");
            }
            // 清除密码字段，不返回给前端
            user.setPassword(null);
            return user;
        } catch (IllegalArgumentException e) {
            throw e;
        } catch (Exception e) {
            log.error("查询用户信息时发生异常", e);
            throw new RuntimeException("查询用户信息失败", e);
        }
    }
    
    /**
     * 根据用户名获取用户信息
     * @param username 用户名
     * @return 用户信息
     */
    @Override
    public UserDTO getUserByUsername(String username) {
        try {
            log.info("查询用户信息，用户名: {}", username);
            if (username == null || username.trim().isEmpty()) {
                throw new IllegalArgumentException("用户名不能为空");
            }
            UserDTO user = userMapper.selectByUsername(username);
            if (user == null) {
                log.warn("用户不存在，用户名: {}", username);
                throw new IllegalArgumentException("用户不存在");
            }
            // 清除密码字段
            user.setPassword(null);
            return user;
        } catch (IllegalArgumentException e) {
            throw e;
        } catch (Exception e) {
            log.error("查询用户信息时发生异常", e);
            throw new RuntimeException("查询用户信息失败", e);
        }
    }
    
    /**
     * 修改密码
     * @param request 修改密码请求
     * @return 是否修改成功
     */
    @Override
    public boolean changePassword(ChangePasswordRequest request) {
        try {
            log.info("收到密码修改请求，用户ID: {}, 用户名: {}", request.getUserId(), request.getUsername());
            
            // 参数验证
            if (request.getNewPassword() == null || request.getNewPassword().trim().isEmpty()) {
                log.warn("密码修改失败：新密码为空");
                throw new IllegalArgumentException("新密码不能为空");
            }
            
            if (request.getNewPassword().length() < 6) {
                log.warn("密码修改失败：新密码长度不足");
                throw new IllegalArgumentException("新密码长度至少6位");
            }
            
            // 验证新密码和确认密码是否一致
            if (request.getConfirmPassword() != null && 
                !request.getNewPassword().equals(request.getConfirmPassword())) {
                log.warn("密码修改失败：两次输入的密码不一致");
                throw new IllegalArgumentException("两次输入的密码不一致");
            }
            
            UserDTO user = null;
            
            // 根据用户ID或用户名查询用户
            if (request.getUserId() != null) {
                user = userMapper.selectByUserId(request.getUserId());
            } else if (request.getUsername() != null && !request.getUsername().trim().isEmpty()) {
                user = userMapper.selectByUsername(request.getUsername());
            } else {
                log.warn("密码修改失败：未提供用户ID或用户名");
                throw new IllegalArgumentException("用户ID或用户名不能为空");
            }
            
            if (user == null) {
                log.warn("密码修改失败：用户不存在");
                throw new IllegalArgumentException("用户不存在");
            }
            
            // 如果提供了旧密码，需要验证旧密码是否正确（用户自己修改密码）
            if (request.getOldPassword() != null && !request.getOldPassword().trim().isEmpty()) {
                if (!request.getOldPassword().equals(user.getPassword())) {
                    log.warn("密码修改失败：旧密码错误，用户ID: {}", user.getUserId());
                    throw new IllegalArgumentException("旧密码错误");
                }
            }
            
            // 检查新密码是否与旧密码相同
            if (request.getNewPassword().equals(user.getPassword())) {
                log.warn("密码修改失败：新密码与旧密码相同，用户ID: {}", user.getUserId());
                throw new IllegalArgumentException("新密码不能与旧密码相同");
            }
            
            // 更新密码
            int result;
            if (request.getUserId() != null) {
                result = userMapper.updatePasswordById(user.getUserId(), request.getNewPassword());
            } else {
                result = userMapper.updatePasswordByUsername(user.getUsername(), request.getNewPassword());
            }
            
            if (result > 0) {
                log.info("密码修改成功，用户ID: {}, 用户名: {}", user.getUserId(), user.getUsername());
                return true;
            } else {
                log.warn("密码修改失败：数据库更新失败，用户ID: {}", user.getUserId());
                throw new RuntimeException("密码修改失败");
            }
            
        } catch (IllegalArgumentException e) {
            throw e;
        } catch (Exception e) {
            log.error("密码修改过程发生异常", e);
            throw new RuntimeException("密码修改失败，请稍后再试", e);
        }
    }
    
    /**
     * 生成token
     * 简单实现：使用UUID
     * 实际项目应使用JWT或其他安全的token生成方式
     */
    private String generateToken(UserDTO user) {
        return UUID.randomUUID().toString().replace("-", "") + "_" + user.getUserId();
    }
}
